package com.woniuxy.health.manager.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.health.manager.dto.AccountDto;
import com.woniuxy.health.manager.dto.ManagerDto;
import com.woniuxy.health.manager.mapper.ManagerMapper;
import com.woniuxy.health.manager.mapper.ManagerRoleMapper;
import com.woniuxy.health.manager.mapper.RoleMapper;
import com.woniuxy.health.manager.vo.ManagerVo;
import com.woniuxy.health.manager.vo.PageVo;
import com.woniuxy.health.medical.mapper.DepartmentMapper;
import com.woniuxy.health.model.manager.Department;
import com.woniuxy.health.model.manager.Manager;
import com.woniuxy.health.manager.service.IManagerService;
import com.woniuxy.health.model.manager.ManagerRole;
import com.woniuxy.health.model.manager.Role;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.baomidou.mybatisplus.core.toolkit.SystemClock.now;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author woniuxy
 * @since 2023-09-04
 */
@Service
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, Manager> implements IManagerService {

    private final ManagerMapper managerMapper;
    private final ManagerRoleMapper managerRoleMapper;
    private final RoleMapper roleMapper;
    private final DepartmentMapper departmentMapper;

    @Autowired
    public ManagerServiceImpl(ManagerMapper managerMapper, ManagerRoleMapper managerRoleMapper, RoleMapper roleMapper, DepartmentMapper departmentMapper) {
        this.managerMapper = managerMapper;
        this.managerRoleMapper = managerRoleMapper;
        this.roleMapper = roleMapper;
        this.departmentMapper = departmentMapper;
    }

    @Override
    public Manager login(ManagerDto managerDto) {

        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
                .eq(Manager::getAccount, managerDto.getAccount())
                .eq(Manager::getPassword, managerDto.getPassword()));
        return manager;
    }

    @Override
    public PageVo<ManagerVo> findAllPage(Page<Manager> page, AccountDto accountDto) {
        Page<Manager> rolePage = managerMapper.selectPage(page, Wrappers.lambdaQuery(Manager.class)
                .likeRight(StringUtils.hasLength(accountDto.getAccount()), Manager::getAccount, accountDto.getAccount())
                .likeRight(StringUtils.hasLength(accountDto.getNickName()), Manager::getNickName, accountDto.getNickName())
                .eq(accountDto.getState() != null, Manager::getState, accountDto.getState())
                .ge(accountDto.getStartDateTime() != null, Manager::getCreateTime, accountDto.getStartDateTime())
                .lt(accountDto.getEndDateTime() != null, Manager::getCreateTime, accountDto.getEndDateTime())
                .inSql(Objects.nonNull(accountDto.getRoleId()), Manager::getId, "SELECT manager_id FROM sys_manager_role WHERE delete_flag=0 AND role_id = " + accountDto.getRoleId()));
        List<Manager> managers = rolePage.getRecords();
        List<ManagerVo> managerVos = new ArrayList<>();
        for (Manager manager : managers) {
            String deptName = null;
            if (Objects.nonNull(manager.getDepartmentId())) {
                deptName = departmentMapper.selectOne(Wrappers.lambdaQuery(Department.class)
                        .eq(Department::getId, manager.getDepartmentId())).getDeptName();
            }
            ManagerVo managerVo = new ManagerVo();
            BeanUtils.copyProperties(manager, managerVo);
            managerVo.setDeptName(deptName);
            // 根据管理员ID查询管理员角色ID
            List<ManagerRole> managerRoles = managerRoleMapper.selectList(Wrappers.lambdaQuery(ManagerRole.class)
                    .eq(Objects.nonNull(manager.getId()), ManagerRole::getManagerId, manager.getId()));
            List<Long> roleIds = managerRoles.stream()
                    .map(ManagerRole::getRoleId)
                    .collect(Collectors.toList());
            if (!roleIds.isEmpty()) {
                StringBuilder roleNameBuilder = new StringBuilder();
                roleIds.forEach(e -> {
                    // 根据角色ID查询角色名称
                    Role role = roleMapper.selectOne(Wrappers.lambdaQuery(Role.class)
                            .eq(Role::getId, e));
                    roleNameBuilder.append("/");
                    roleNameBuilder.append(role.getRoleName());
                });
                String roleName = roleNameBuilder.toString();
                managerVo.setRoleName(roleName);
                managerVos.add(managerVo);
            } else {
                managerVo.setRoleName(null);
                managerVos.add(managerVo);
            }
        }
        PageVo<ManagerVo> pageVo = new PageVo<>(rolePage.getTotal(), managerVos);
        return pageVo;
    }

    @Override
    public Manager findByAccount(String managerInfo) {
        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
                .eq(Manager::getAccount, managerInfo));
        return manager;
    }

    @Override
    public Manager findByNickName(String managerInfo) {
        Manager manager = managerMapper.selectOne(Wrappers.lambdaQuery(Manager.class)
                .eq(Manager::getNickName, managerInfo));
        return manager;
    }

    @Transactional(isolation = Isolation.REPEATABLE_READ)
    @Override
    public void deleteManager(Long id) {
        //与角色表
        managerRoleMapper
                .delete(Wrappers.lambdaQuery(ManagerRole.class)
                        .eq(ManagerRole::getManagerId, id));
        //删除自己
        managerMapper.deleteById(id);
    }

}
